//============================================================================
// Copyright (C) 2010 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================
// manage which game state is active.. ie menu/play/ etc
enum EGameStateStep 
{
	eGameStateStepInvalid	= 0,	// selected state not yet initialized
	eGameStateStepStartup	= 1,	// starting current selected state
	eGameStateStepUpdate	= 2,	// update current state
	eGameStateStepShutdown	= 3		// shutdown current state
};
enum EContinent
{
	eContinentArtic				=	0x00ff0000,	
	eContinentNorthAmerica		=	0x00ffff00,	
	eContinentSouthAmerica		=	0x0000B5B5,	
	eContinentAnartic			=	0x00ff00ff,	
	eContinentEurope			=	0x006C0000,	
	eContinentGreenland			=	0x0000ff00,	
	eContinentAsia				=	0x00760076,	
	eContinentAfrica			=	0x00008500,	
	eContinentAustralia			=	0x00000080,	

	eMaxContinent = 8
};


class DtwGameMgr : public VxIrrBase, public GameInputBase
{
public:
	//=== vars ===//
	BOOL								m_bIsRunning;			// if true then is loaded and running or paused
	BOOL								m_bIsPaused;			// if true then game is paused
	BOOL								m_bShutdownRequested;	// if true we need to begin clean up and exit
	BOOL								m_bIsShuttingDown;		// if true we are in the process of clean up and exit
	//=== game state vars ===//
	GameStateBase *						m_poCurState;			// current game state ( ie menu, gameplay etc )
	EGameStateStep						m_eStateStep;			// which step in current state
	GameStateBase *						m_poNewState;			// if not null then request has been made to switch to this state

	//=== time vars ===//
	U32									m_u32LastAppTimeMs;

	std::string							m_strAssetsRootPath;
	bool								m_bInitialized;

	DtwGameMgr( const char * externStoragePath );

	virtual ~DtwGameMgr();

	//! return true then is loaded and running or paused
	BOOL	IsRunning( void )					{ return m_bIsRunning; };
	//! set true if is loaded and running or paused
	void	SetIsRunning( BOOL bVal )			{ m_bIsRunning = bVal; }
	//! return true if paused
	BOOL	IsPaused( void )					{ return m_bIsPaused; };
	//! set true if is paused
	void	SetIsPaused( BOOL bVal )			{ m_bIsPaused = bVal; }
	//! toggle is paused or not
	void	TogglePaused( void )				{ m_bIsPaused = m_bIsPaused?0:1; };
	//! return true we need to begin clean up and exit
	BOOL	IsShutdownRequested( void )			{ return m_bShutdownRequested; }
	//! set true if we need to begin clean up and exit
	//! called when exit game button is pressed
	void	SetIsShutdownRequested( BOOL bVal )	{ m_bShutdownRequested = bVal; }
	//! return true we are in the process of clean up and exit
	BOOL	IsShuttingDown( void )				{ return m_bIsShuttingDown; }		
	//! set true if we are in the process of clean up and exit
	void	SetIsShuttingDown( BOOL bVal )		{ m_bIsShuttingDown = bVal; }		

	//! startup
	RCODE 	Startup(	HWND			hWnd,					// handle to window.. if null then create window of size specified
						int				iScreenWidth,			// window width in pixels
						int				iScreenHeight,			// window height in pixels
						const char *	pConfigFile = NULL );	// configuration file if any

	//! shutdown
	void	Shutdown( void );

	//=== screen methods ===//
	//! resize view screen
	void 	ResizeView( int iScreenWidth, int iScreenHeight );

	//=== update ===//
	//! update game.. u32TimeMs is time in millisec since app start
	virtual RCODE	UpdateGame( U32 u32AppTimeMs );

	//=== handle input from devices ===//
	//! called after processed HandleOrientationEvent for derived classes to override
	virtual bool	OnOrientationEvent( F32 f32RotX, F32 f32RotY, F32 f32RotZ  );
	//! called after processed HandleMouseEvent for derived classes to override
	virtual bool	OnMouseEvent( EMouseButtonType eMouseButType, EMouseEventType eMouseEventType, int iMouseXPos, int iMouseYPos  );
	//! called after processed HandleMouseWheel for derived classes to override
	virtual bool	OnMouseWheel( F32 f32MouseWheelDist );
	//! called after processed HandleKeyEvent for derived classes to override
	virtual bool	OnKeyEvent( EKeyEventType eKeyEventType, irr::EKEY_CODE eKey, int iFlags = 0 );
	//! called after processed HandleGuiEvent for derived classes to override
	virtual bool	OnGuiEvent( irr::gui::EGUI_EVENT_TYPE eGuiEventType, irr::gui::IGUIElement * poGuiElement );
	//! called after processed HandleKeyEvent
	virtual bool	OnInputAction( EInputActionType eInputActionType, F32 f32PosX, F32 f32PosY, F32 f32PosZ  );

	//! pause game
	virtual void	OnGamePause( void );
	//! resume game
	virtual void	OnGameResume( void );
	//! restart game
	virtual void	OnGameRestart( void );
	//! restart level
	virtual void	OnLevelRestart( void );


	//! called when application goes to sleep
	virtual void	OnAppSleep( void );
	//! called when application resumes
	virtual void	OnAppResume( U32 u32FrameTimeMs );

	//! irrlicht was restarted.. let derived class do any required restart actions 
	virtual RCODE	OnIrrlichtRestart( void );

	//! override VxIrrBase
	//! called if collision occures
	virtual void HandleCollision(EntBase * poEnt1, EntBase * poEnt2 );
};




